using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using AutoMapper;
using CR.Domain.Entities;
using CR.Application.DTOs;
using CR.Application.Interfaces;
using CR.Infrastructure.Repositories;
using CR.ErrorCode;
using System.Linq.Expressions;

namespace CR.Application.Services
{
    /// <summary>
    /// 养殖信息服务实现
    /// </summary>
    public class BreedingInfoService : IBreedingInfoService
    {
        private readonly IBreedingInfoRepository _breedingInfoRepository;
        private readonly IMapper _mapper;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="breedingInfoRepository">养殖信息仓储</param>
        /// <param name="mapper">对象映射器</param>
        public BreedingInfoService(IBreedingInfoRepository breedingInfoRepository, IMapper mapper)
        {
            _breedingInfoRepository = breedingInfoRepository ?? throw new ArgumentNullException(nameof(breedingInfoRepository));
            _mapper = mapper ?? throw new ArgumentNullException(nameof(mapper));
        }

        /// <inheritdoc/>
        public async Task<ApiResult<IEnumerable<BreedingInfoDTO>>> GetAllBreedingInfosAsync()
        {
            try
            {
                var breedingInfos = await _breedingInfoRepository.GetAllAsync();
                var breedingInfoDTOs = _mapper.Map<IEnumerable<BreedingInfoDTO>>(breedingInfos);
                
                return ApiResult<IEnumerable<BreedingInfoDTO>>.Success(breedingInfoDTOs, "获取养殖信息列表成功");
            }
            catch (Exception ex)
            {
                return ApiResult<IEnumerable<BreedingInfoDTO>>.Fail(ApiEnums.SystemError, $"获取养殖信息失败: {ex.Message}");
            }
        }

        /// <inheritdoc/>
        public async Task<ApiResult<BreedingInfoDTO>> GetBreedingInfoByIdAsync(Guid id)
        {
            try
            {
                var breedingInfo = await _breedingInfoRepository.GetByIdAsync(id);
                if (breedingInfo == null)
                {
                    return ApiResult<BreedingInfoDTO>.Fail(ApiEnums.NotFound, "养殖信息不存在");
                }

                var breedingInfoDTO = _mapper.Map<BreedingInfoDTO>(breedingInfo);
                return ApiResult<BreedingInfoDTO>.Success(breedingInfoDTO, "获取养殖信息成功");
            }
            catch (Exception ex)
            {
                return ApiResult<BreedingInfoDTO>.Fail(ApiEnums.SystemError, $"获取养殖信息失败: {ex.Message}");
            }
        }

        /// <inheritdoc/>
        public async Task<ApiResult<BreedingInfoDTO>> GetBreedingInfoByTraceabilityCodeAsync(string traceabilityCode)
        {
            try
            {
                if (string.IsNullOrWhiteSpace(traceabilityCode))
                {
                    return ApiResult<BreedingInfoDTO>.Fail(ApiEnums.ParameterError, "溯源码不能为空");
                }

                var breedingInfos = await _breedingInfoRepository.FindAsync(b => b.TraceabilityCode == traceabilityCode);
                var breedingInfo = breedingInfos.FirstOrDefault();
                
                if (breedingInfo == null)
                {
                    return ApiResult<BreedingInfoDTO>.Fail(ApiEnums.NotFound, "未找到对应溯源码的养殖信息");
                }

                var breedingInfoDTO = _mapper.Map<BreedingInfoDTO>(breedingInfo);
                return ApiResult<BreedingInfoDTO>.Success(breedingInfoDTO, "获取养殖信息成功");
            }
            catch (Exception ex)
            {
                return ApiResult<BreedingInfoDTO>.Fail(ApiEnums.SystemError, $"获取养殖信息失败: {ex.Message}");
            }
        }

        /// <inheritdoc/>
        public async Task<ApiResult<BreedingInfoDTO>> CreateBreedingInfoAsync(BreedingInfoDTO breedingInfoDto)
        {
            try
            {
                if (breedingInfoDto == null)
                {
                    return ApiResult<BreedingInfoDTO>.Fail(ApiEnums.ParameterError, "养殖信息不能为空");
                }

                // 检查溯源码是否已存在
                if (!string.IsNullOrWhiteSpace(breedingInfoDto.TraceabilityCode))
                {
                    var existingWithCode = await _breedingInfoRepository.FindAsync(b => b.TraceabilityCode == breedingInfoDto.TraceabilityCode);
                    if (existingWithCode.Any())
                    {
                        return ApiResult<BreedingInfoDTO>.Fail(ApiEnums.BadRequest, "溯源码已被使用");
                    }
                }

                // 设置ID (如果未提供)
                if (breedingInfoDto.Id == Guid.Empty)
                {
                    breedingInfoDto.Id = Guid.NewGuid();
                }

                var breedingInfo = _mapper.Map<BreedingInfo>(breedingInfoDto);
                var createdBreedingInfo = await _breedingInfoRepository.AddAsync(breedingInfo);
                var createdBreedingInfoDto = _mapper.Map<BreedingInfoDTO>(createdBreedingInfo);

                return ApiResult<BreedingInfoDTO>.Success(createdBreedingInfoDto, "养殖信息创建成功");
            }
            catch (Exception ex)
            {
                return ApiResult<BreedingInfoDTO>.Fail(ApiEnums.SystemError, $"创建养殖信息失败: {ex.Message}");
            }
        }

        /// <inheritdoc/>
        public async Task<ApiResult<BreedingInfoDTO>> UpdateBreedingInfoAsync(Guid id, BreedingInfoDTO breedingInfoDto)
        {
            try
            {
                var existingBreedingInfo = await _breedingInfoRepository.GetByIdAsync(id);
                if (existingBreedingInfo == null)
                {
                    return ApiResult<BreedingInfoDTO>.Fail(ApiEnums.NotFound, "养殖信息不存在");
                }

                // 检查溯源码是否被其他记录使用
                if (!string.IsNullOrWhiteSpace(breedingInfoDto.TraceabilityCode) && 
                    breedingInfoDto.TraceabilityCode != existingBreedingInfo.TraceabilityCode)
                {
                    var existingWithCode = await _breedingInfoRepository.FindAsync(b => b.TraceabilityCode == breedingInfoDto.TraceabilityCode);
                    if (existingWithCode.Any())
                    {
                        return ApiResult<BreedingInfoDTO>.Fail(ApiEnums.BadRequest, "溯源码已被其他记录使用");
                    }
                }

                // 更新实体属性
                _mapper.Map(breedingInfoDto, existingBreedingInfo);
                existingBreedingInfo.UpdatedAt = DateTime.Now;

                var updatedBreedingInfo = await _breedingInfoRepository.UpdateAsync(existingBreedingInfo);
                var updatedBreedingInfoDto = _mapper.Map<BreedingInfoDTO>(updatedBreedingInfo);

                return ApiResult<BreedingInfoDTO>.Success(updatedBreedingInfoDto, "养殖信息更新成功");
            }
            catch (Exception ex)
            {
                return ApiResult<BreedingInfoDTO>.Fail(ApiEnums.SystemError, $"更新养殖信息失败: {ex.Message}");
            }
        }

        /// <inheritdoc/>
        public async Task<ApiResult> DeleteBreedingInfoAsync(Guid id)
        {
            try
            {
                var existingBreedingInfo = await _breedingInfoRepository.GetByIdAsync(id);
                if (existingBreedingInfo == null)
                {
                    return ApiResult.Fail(ApiEnums.NotFound, "养殖信息不存在");
                }

                var result = await _breedingInfoRepository.RemoveAsync(existingBreedingInfo);
                if (result)
                {
                    return ApiResult.Success("养殖信息删除成功");
                }
                else
                {
                    return ApiResult.Fail(ApiEnums.SystemError, "养殖信息删除失败");
                }
            }
            catch (Exception ex)
            {
                return ApiResult.Fail(ApiEnums.SystemError, $"删除养殖信息失败: {ex.Message}");
            }
        }

        /// <inheritdoc/>
        public async Task<ApiResult<ApiPagin<BreedingInfoDTO>>> GetPagedBreedingInfosAsync(
            int pageIndex, 
            int pageSize, 
            string breed = null, 
            DateTime? startDateFrom = null, 
            DateTime? startDateTo = null)
        {
            try
            {
                // 构建查询条件
                Expression<Func<BreedingInfo, bool>> predicate = b => true; // 默认返回所有记录
                
                if (!string.IsNullOrEmpty(breed) || startDateFrom.HasValue || startDateTo.HasValue)
                {
                    predicate = b => 
                        (string.IsNullOrEmpty(breed) || b.Breed.Contains(breed)) &&
                        (!startDateFrom.HasValue || b.StartDate >= startDateFrom.Value) &&
                        (!startDateTo.HasValue || b.StartDate <= startDateTo.Value);
                }

                // 分页查询
                var (data, total) = await _breedingInfoRepository.GetPagedListAsync(
                    pageIndex, 
                    pageSize, 
                    predicate, 
                    b => b.StartDate, 
                    false);

                // 映射到DTO
                var breedingInfoDtos = _mapper.Map<IEnumerable<BreedingInfoDTO>>(data);

                // 构建分页结果
                var pagedResult = new ApiPagin<BreedingInfoDTO>
                {
                    PageIndex = pageIndex,
                    PageSize = pageSize,
                    TotalCount = total,
                    TotalPages = (int)Math.Ceiling(total / (double)pageSize),
                    Items = breedingInfoDtos
                };

                return ApiResult<ApiPagin<BreedingInfoDTO>>.Success(pagedResult, "获取养殖信息分页数据成功");
            }
            catch (Exception ex)
            {
                return ApiResult<ApiPagin<BreedingInfoDTO>>.Fail(ApiEnums.SystemError, $"获取养殖信息分页数据失败: {ex.Message}");
            }
        }
    }
} 